#include "gamepanel.h"
#include "ui_gamepanel.h"
#include <QThread>
#include <qpainter.h>
#include <QRandomGenerator>
#include <QDebug>
GamePanel::GamePanel(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::GamePanel)
{
    ui->setupUi(this);

    //背景图
    int index = QRandomGenerator::global()->bounded(10);
    QString path = QString(":/images/background-%1.png").arg(index+1);
    background_image_.load(path);

    //窗口标题
    this->setWindowTitle("我爱斗地主");
    this->setFixedSize(1000,650);

    //实例化游戏控制类对象
    Game_Control_Init();

    //玩家分数
    Update_Player_Score();

    //切割游戏图片
    Init_Card_Map();

    //初始化游戏中的按钮组
    Init_Button_Group();

    //初始化玩家在窗口的上下文环境
    Init_Player_Context();

    //扑克牌场景初始化
    Init_Game_Scene();

    //定时器实例化
    timer_ = new QTimer(this);
    connect(timer_, &QTimer::timeout, this, &GamePanel::On_Dispatch_Card);
}

GamePanel::~GamePanel()
{
    delete ui;
}

void GamePanel::paintEvent(QPaintEvent *ev)
{
    QPainter draw(this);
    draw.drawPixmap(rect(),background_image_);
}

void GamePanel::Game_Control_Init()
{
    game_ctl_ = new GameControl(this);
    game_ctl_->Player_Init();
    player_list_ << game_ctl_->Get_Left_Robot();
    player_list_ << game_ctl_->Get_Right_Robot();
    player_list_ << game_ctl_->Get_User_Player();
}

void GamePanel::Update_Player_Score()
{
    ui->score_panel_widget_->Set_Scores(
                            player_list_[0]->Get_Score(),
                            player_list_[1]->Get_Score(),
                            player_list_[2]->Get_Score());
}

void GamePanel::Init_Card_Map()
{
    QPixmap pixmap(":/images/card.png");
    //计算每张牌的大小
    card_size_.setWidth(pixmap.width()/13);
    card_size_.setHeight(pixmap.height()/5);
    //背景图
    card_background_image_ = pixmap.copy(2*card_size_.width(),
                                         4*card_size_.height(),
                                         card_size_.width(),
                                         card_size_.height());

    //正常花色
    for(int i = 0,suit = Card::CardSuit::Suit_Begin+1; suit < Card::CardSuit::Suit_End; ++suit,++i)
    {
        for(int j = 0,pt = Card::CardPoint::Card_Begin+1; pt < Card::CardPoint::Card_Small_Joker; ++pt,++j)
        {
            Card card((Card::CardPoint)pt,(Card::CardSuit)suit);
            //裁剪图片
            Crop_Image(pixmap,j*card_size_.width(),i*card_size_.height(),card);
        }
    }
    //大小王
    Card bj;
    bj.Set_Point(Card::Card_Big_Joker);
    bj.Set_Suit(Card::Suit_Begin);
    Crop_Image(pixmap,0,4*card_size_.height(), bj);

    Card sj;
    sj.Set_Point(Card::Card_Small_Joker);
    sj.Set_Suit(Card::Suit_Begin);
    Crop_Image(pixmap,card_size_.width(),4*card_size_.height(), sj);
}

void GamePanel::Crop_Image(const QPixmap &pix, int x, int y, const Card &card)
{
    QPixmap sub = pix.copy(x,y,card_size_.width(),card_size_.height());
    CardPanel* panel = new CardPanel(this);
    panel->Set_Image(sub,card_background_image_);
    panel->Set_Card(card);
    panel->hide();
    card_map_.insert(card,panel);
}

void GamePanel::Init_Button_Group()
{
    ui->button_group_widget_->Init_Buttons();
    ui->button_group_widget_->Select_Panel(ButtonGroup::Start);

    connect(ui->button_group_widget_, &ButtonGroup::Start_Game,this,[=](){
        //界面初始化
        ui->button_group_widget_->Select_Panel(ButtonGroup::Empty);
        game_ctl_->Clear_Player_Score();
        Update_Player_Score();
        //修改玩家状态 -> 发牌
        Game_Status_Precess(GameControl::DispatchCard);
    });
    connect(ui->button_group_widget_, &ButtonGroup::Play_Hand,this,[=](){});
    connect(ui->button_group_widget_, &ButtonGroup::Pass,this,[=](){});
    connect(ui->button_group_widget_, &ButtonGroup::Bet_Ponit,this,[=](){});
}

void GamePanel::Init_Player_Context()
{
    //放置玩家扑克牌的区域
    QRect cards_rect[] =
    {
        QRect(90,130,100,height()-200),
        QRect(rect().right()-190,130,100,height()-200),
        QRect(250,rect().bottom()-120,width()-500,100)
    };

    //玩家出牌区域
    QRect play_hand_rect[] =
    {
        QRect(260,150,100,100),
        QRect(rect().right()-360,150,100,100),
        QRect(150,rect().bottom()-290,width()-300,105)
    };

    //玩家头像显示区域
    QPoint role_img_pos[] =
    {
        QPoint(cards_rect[0].left()-80,cards_rect[0].height()/2+20),
        QPoint(cards_rect[1].left()+10,cards_rect[1].height()/2+20),
        QPoint(cards_rect[2].right()-10,cards_rect[2].top()-10)
    };

    int index = player_list_.indexOf(game_ctl_->Get_User_Player());
    for(int i = 0; i < player_list_.size(); ++i)
    {
        PlayerContext context;
        context.align_ = i == index ? Horizontal : Vertical;
        context.is_front_side_ = i == index ? true : false;
        context.card_rect_ = cards_rect[i];
        context.play_hand_rect_= play_hand_rect[i];

        //提示信息
        context.info_ = new QLabel(this);
        context.info_->resize(160,98);
        context.info_->hide();

        //显示到出牌区域的中心位置
        QRect rect = play_hand_rect[i];
        QPoint pt(rect.left() + (rect.width() - context.info_->width())/2,
                  rect.top() + (rect.height() - context.info_->height()/2));
        context.info_->move(pt);

        //玩家头像
        context.role_img_ = new QLabel(this);
        context.role_img_->resize(84,120);
        context.role_img_->hide();
        context.role_img_->move(role_img_pos[i]);
        context_map_.insert(player_list_.at(i),context);
    }

}

void GamePanel::Init_Game_Scene()
{
    // 发牌区的扑克牌
    base_card_ = new CardPanel(this);
    base_card_->Set_Image(card_background_image_,card_background_image_);
    // 发牌过程中的移动的扑克牌
    move_card_ = new CardPanel(this);
    move_card_->Set_Image(card_background_image_,card_background_image_);
    // 最后的三张的底牌（窗口显示）
    for(int i = 0; i < 3; ++i)
    {
        CardPanel* panel = new CardPanel(this);
        panel->Set_Image(card_background_image_,card_background_image_);
        last_three_cards_.push_back(panel);
        panel->hide();
    }
    // 扑克牌位置
    base_card_pos_ = QPoint((width() - card_size_.width())/2, height() / 2 -100);
    base_card_->move(base_card_pos_);
    move_card_->move(base_card_pos_);

    int base = (width() - 3*card_size_.width() - 2*10) / 2;
    for(int i = 0; i < 3; ++i)
    {
        last_three_cards_[i]->move(base + (card_size_.width() + 10)*i,20);
    }
}

void GamePanel::Game_Status_Precess(GameControl::GameStatus status)
{
    //记录游戏状态
    game_status_ = status;
    //处理游戏状态
    switch(game_status_)
    {
    case GameControl::DispatchCard:
        Start_Dispatch_Card();
        break;
    case GameControl::CallingLord:
        break;
    case GameControl::PlayingHand:
        break;
    default:
        break;
    }
}

void GamePanel::Start_Dispatch_Card()
{
    //初始化每张卡牌
    for(auto it = card_map_.begin(); it != card_map_.end(); ++it)
    {
        it.value()->Set_Selected(false);
        it.value()->Set_Front_Or_Back_Side(true);
        it.value()->hide();
    }
    //隐藏三张底牌
    for(int i = 0; i < last_three_cards_.size(); ++i)
    {
        last_three_cards_.at(i)->hide();
    }
    //重置玩家的窗口上下文信息
    int index = player_list_.indexOf(game_ctl_->Get_User_Player());
    for(int i = 0; i < player_list_.size(); ++i)
    {
        context_map_[player_list_.at(i)].last_cards_.Clear();
        context_map_[player_list_.at(i)].info_->hide();
        context_map_[player_list_.at(i)].role_img_->hide();
        context_map_[player_list_.at(i)].is_front_side_ = i==index ? true : false;
    }
    //重置所有玩家的卡牌数据
    game_ctl_->Reset_Cards_Data();
    //显示底牌
    base_card_->show();
    //隐藏按钮面板
    ui->button_group_widget_->Select_Panel(ButtonGroup::Empty);

    //启动定时器
    timer_->start(10);
    //播放背景音乐
}

void GamePanel::Card_Move_Step(Player* player, int curpos)
{
    //得到每个玩家的扑克牌展示区域
    QRect cardrect = context_map_[player].card_rect_;
    //每个玩家的单元步长
    const int unit[] = {
        (base_card_pos_.x() - cardrect.right())/100,
        (cardrect.left() - base_card_pos_.x())/100,
        (cardrect.top() - base_card_pos_.y())/100
    };

    //每次窗口移动的时候每个玩家对应的牌的实时坐标位置
    const QPoint pos[] =
    {
        QPoint(base_card_pos_.x() - curpos*unit[0],base_card_pos_.y()),
        QPoint(base_card_pos_.x() + curpos*unit[1],base_card_pos_.y()),
        QPoint(base_card_pos_.x(), base_card_pos_.y() + curpos*unit[2]),
    };

    //移动扑克牌窗口
    int index = player_list_.indexOf(player);
    move_card_->move(pos[index]);

    //临界状态处理
    if(curpos == 0)
    {
        move_card_->show();
    }

    if(curpos == 100)
    {
        move_card_->hide();
    }
}


void GamePanel::Update_Player_Cards(Player *player)
{
    Cards cards = player->Get_Cards();
    CardList list = cards.To_CardList();

    int cardSpace = 20;
    QRect cardsRect = context_map_[player].card_rect_;
    for(int i=0; i<list.size(); ++i)
    {
        CardPanel* panel = card_map_[list.at(i)];
        panel->show();
        panel->raise();
        panel->Set_Front_Or_Back_Side(context_map_[player].is_front_side_);

        // 水平 or 垂直显示
        if(context_map_[player].align_ == Horizontal)
        {
            int leftX = cardsRect.left() + (cardsRect.width() - (list.size() - 1) * cardSpace - panel->width()) / 2;
            int topY = cardsRect.top() + (cardsRect.height() - card_size_.height()) / 2;
            if(panel->Is_Selected())
            {
                topY -= 10;
            }
            panel->move(leftX + cardSpace * i, topY);
        }
        else
        {
            int leftX = cardsRect.left() + (cardsRect.width() - card_size_.width()) / 2;
            int topY = cardsRect.top() + (cardsRect.height() - (list.size() - 1) * cardSpace - panel->height()) / 2;
            panel->move(leftX, topY + i * cardSpace);
        }
    }
}



void GamePanel::Dispose_Card(Player *player, const Cards &cards)
{
    Cards& mycard = const_cast<Cards&>(cards);
    CardList list = mycard.To_CardList();
    static int count = 0;
    for(int i = 0; i < list.size(); ++i)
    {
        CardPanel* panel = card_map_[list.at(i)];
        panel->Set_Owner(player);
    }
    Update_Player_Cards(player);
}


void GamePanel::On_Dispatch_Card()
{
    //记录扑克牌的位置
    static int curmovepos = 0;
    //当前玩家
    Player* curplayer = game_ctl_->Get_Current_Player();
    if(curmovepos >= 100)
    {
        //给玩家一张牌
        Card card = game_ctl_->Take_One_Card();
        curplayer->Store_Dispatch_Card(card);
        Dispose_Card(curplayer,Cards(card));
        //切换玩家
        game_ctl_->Set_Current_Player(curplayer->Get_Next_Player());
        curmovepos = 0;
        //发牌动画
        Card_Move_Step(curplayer,curmovepos);
        //判断是否发完
        if(game_ctl_->Get_Surplus_Cards().Card_Count() == 3)
        {
            //终止定时器
            timer_->stop();
            //切换游戏状态
            Game_Status_Precess(GameControl::CallingLord);
            return;
        }
    }
    //移动扑克牌
    Card_Move_Step(curplayer,curmovepos);
    curmovepos += 15;

}
















